package cc.rengu.oltp.utility.util;

import cc.rengu.jradp.mods.message.MessageTree;
import cc.rengu.utility.xml.XmlError;
import cc.rengu.utility.xml.XmlValue;

import java.util.List;

import com.alibaba.fastjson.JSON;

/**
 * Created by 王成 on 2017/4/19.
 * 内部XML树工具类方法
 */
public class XmlTreeUtil {
    private XmlError xmlError;
    private XmlValue xmlValue;
    private MessageTree xmlTree;

    public XmlTreeUtil() {
        xmlError = new XmlError();
        xmlValue = new XmlValue();
        xmlTree = new MessageTree();
    }

    /**
     * 从XML树中获取节点的字节值
     *
     * @param xmlPath XML路径节点
     * @return 节点值
     * @throws Exception 异常
     */
    public byte[] getXmlTreeByteValue(String xmlPath) throws Exception {
        if (null == xmlPath) {
            return null;
        } else {
            if (null == xmlTree.getValue(xmlPath, xmlError)) {
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    return null;
                }
            } else {
                xmlValue = xmlTree.getValue(xmlPath, xmlError);
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    return xmlValue.toBinary();
                }
            }
        }
    }

    /**
     * 从XML树中获取节点的长整型值
     *
     * @param xmlPath XML树节点路径
     * @return XML树的长整型值
     */
    public Long getXmlTreeLongValue(String xmlPath) throws Exception {
        if (null == xmlPath) {
            throw new Exception("XML节点路径为NULL!");
        } else {
            if (null == xmlTree.getValue(xmlPath, xmlError)) {
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    throw new Exception("无此XML节点路径对应的值!");
                }
            } else {
                xmlValue = xmlTree.getValue(xmlPath, xmlError);
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    if (null == xmlValue) {
                        throw new Exception("无此XML节点路径对应的值!");
                    } else {
                        return Long.parseLong(xmlValue.getText());
                    }
                }
            }
        }
    }

    /**
     * 从XML树中获取节点的字符串值
     *
     * @param xmlPath XML路径节点
     * @return 节点值
     */
    public String getXmlTreeStringValue(String xmlPath) throws Exception {
        if (null == xmlPath) {
            return null;
        } else {
            if (null == xmlTree.getValue(xmlPath, xmlError)) {
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    return null;
                }
            } else {
                xmlValue = xmlTree.getValue(xmlPath, xmlError);
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    return xmlValue.getText();
                }
            }
        }
    }

    /**
     * 从XML树中获取节点的int值
     *
     * @param xmlPath XML树节点路径
     * @return 节点值
     */
    public Integer getXmlTreeIntegerValue(String xmlPath) throws Exception {
        if (null == xmlPath) {
            throw new Exception("XML节点路径为NULL!");
        } else {
            if (null == xmlTree.getValue(xmlPath, xmlError)) {
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    throw new Exception("无此XML节点路径对应的值!");
                }
            } else {
                xmlValue = xmlTree.getValue(xmlPath, xmlError);
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    if (null == xmlValue) {
                        throw new Exception("无此XML节点路径对应的值!");
                    } else {
                        return xmlValue.toInteger();
                    }
                }
            }
        }
    }

    /**
     * 从XML树中获取节点的Object值
     *
     * @param xmlPath XML树节点路径
     * @param clasz   目标对象类
     * @return Object对象
     * @throws Exception XML树操作异常
     */
    public Object getXmlTreeObjectValue(String xmlPath, Class clasz) throws Exception {
        if (null == xmlPath) {
            return null;
        } else {
            if (null == xmlTree.getValue(xmlPath, xmlError)) {
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    return null;
                }
            } else {
                xmlValue = xmlTree.getValue(xmlPath, xmlError);
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    if (null == xmlValue) {
                        return null;
                    } else {
                        return JSON.parseObject(xmlValue.getText(), clasz);
                    }
                }
            }
        }
    }

    /**
     * 从XML树中获取节点的Object值（List对象）
     *
     * @param xmlPath XML树节点路径
     * @param clasz   目标对象类
     * @return List对象
     * @throws Exception XML树操作异常
     */
    public List getXmlTreeListObjectValue(String xmlPath, Class clasz) throws Exception {
        if (null == xmlPath) {
            return null;
        } else {
            if (null == xmlTree.getValue(xmlPath, xmlError)) {
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    return null;
                }
            } else {
                xmlValue = xmlTree.getValue(xmlPath, xmlError);
                if (xmlError.isFailure()) {
                    throw new Exception(xmlError.getErrorInfo());
                } else {
                    if (null == xmlValue) {
                        return null;
                    } else {
                        return JSON.parseArray(xmlValue.getText(), clasz);
                    }
                }
            }
        }
    }

    /**
     * 将长整型设置到XML树中
     *
     * @param xmlPath   XML树节点路径
     * @param longValue 节点值
     */
    public void setXmlTreeLongValue(String xmlPath, Long longValue) throws Exception {
        xmlValue.setText(longValue);
        xmlError = xmlTree.setValue(xmlPath, xmlValue);
        if (xmlError.isFailure()) {
            throw new Exception(xmlError.getErrorInfo());
        }
    }

    /**
     * 将字节数组设置到XML树中
     *
     * @param xmlPath   XML树节点路径
     * @param byteValue 节点值
     */
    public void setXmlTreeByteValue(String xmlPath, byte[] byteValue) throws Exception {
        xmlValue.setText(byteValue);
        xmlError = xmlTree.setValue(xmlPath, xmlValue);
        if (xmlError.isFailure()) {
            throw new Exception(xmlError.getErrorInfo());
        }
    }

    /**
     * 将字符串设置到XML树中
     *
     * @param xmlPath  XML树节点路径
     * @param strValue 节点值
     */
    public void setXmlTreeStringValue(String xmlPath, String strValue) throws Exception {
        xmlValue.setText(strValue);
        xmlError = xmlTree.setValue(xmlPath, xmlValue);
        if (xmlError.isFailure()) {
            throw new Exception(xmlError.getErrorInfo());
        }
    }

    /**
     * 将对象设置到XML树中
     *
     * @param xmlPath XML树节点路径
     * @param object  设置对象
     * @throws Exception XML树操作异常
     */
    public void setXmlTreeObjectValue(String xmlPath, Object object) throws Exception {
        xmlValue.setText(JSON.toJSONString(object));
        xmlError = xmlTree.setValue(xmlPath, xmlValue);
        if (xmlError.isFailure()) {
            throw new Exception(xmlError.getErrorInfo());
        }
    }

    /**
     * 将INT值设置到XML树中
     *
     * @param xmlPath  XML树节点路径
     * @param intValue 节点值
     */
    public void setXmlTreeIntValue(String xmlPath, int intValue) throws Exception {
        xmlValue.setText(intValue);
        xmlError = xmlTree.setValue(xmlPath, xmlValue);
        if (xmlError.isFailure()) {
            throw new Exception(xmlError.getErrorInfo());
        }
    }

    /**
     * 删除XML树中的节点及子节点
     *
     * @param xmlPath XML树节点路径
     */
    public void deleteXmlTreeNode(String xmlPath) {
        xmlTree.deleteNode(xmlPath);
    }

    /**
     * 将业务报文树序列化成紧凑格式的XML字符串
     *
     * @return XML字符串
     */
    @Override
    public String toString() {
        return xmlTree.toString();
    }

    /**
     * 将XML字符反序列化成业务报文树
     *
     * @param xmlString XML字符串
     * @throws Exception 异常
     */
    public void loadXmlString(String xmlString) throws Exception {
        xmlError = xmlTree.loadString(xmlString);
        if (xmlError.isFailure()) {
            throw new Exception(xmlError.getErrorInfo());
        }
    }

    /**
     * 判断制定目录节点是否存在
     *
     * @param xmlPath XML树内部节点路径
     * @return true-存在，false-不存在
     */
    public boolean isExist(String xmlPath) {
        XmlError xmlExistError = new XmlError();
        XmlValue xmlExistValue = xmlTree.getValue(xmlPath, xmlExistError);
        if (xmlExistError.isSuccess()) {
            if (null == xmlExistValue || null == xmlExistValue.getText()) {
                return false;
            } else {
                return true;
            }
        }
        return false;
    }

    /**
     * 将原路径String值复制到目的路径中
     *
     * @param srcPath  原节点路径
     * @param destPath 目标节点路径
     * @throws Exception 处理异常
     */
    public void copyStringValue(String srcPath, String destPath) throws Exception {
        setXmlTreeStringValue(destPath, getXmlTreeStringValue(srcPath));
    }

    /**
     * 将原路径Integer值复制到目的路径中
     *
     * @param srcPath  原节点路径
     * @param destPath 目标节点路径
     * @throws Exception 处理异常
     */
    public void copyIntegerValue(String srcPath, String destPath) throws Exception {
        setXmlTreeIntValue(destPath, getXmlTreeIntegerValue(srcPath));
    }

    /**
     * 将原路径Long值复制到目的路径中
     *
     * @param srcPath  原节点路径
     * @param destPath 目标节点路径
     * @throws Exception 处理异常
     */
    public void copyLongValue(String srcPath, String destPath) throws Exception {
        setXmlTreeLongValue(destPath, getXmlTreeLongValue(srcPath));
    }

    /**
     * 将原路径object值复制到目的路径中
     *
     * @param srcPath  原节点路径
     * @param destPath 目标节点路径
     * @param clasz    目标对象类
     * @throws Exception 处理异常
     */
    public void copyObjectValue(String srcPath, String destPath, Class clasz) throws Exception {
        setXmlTreeObjectValue(destPath, getXmlTreeObjectValue(srcPath, clasz));
    }
}
